#ifndef __ATA_H
#define __ATA_H

#define ATA_TIMEOUT		100000

#define ATA_MASTER_LBA_28		0xE0
#define ATA_SLAVE_LBA_28		0xF0

#define ATA_MASTER_LBA_48		0x40
#define ATA_SLAVE_LBA_48		0x50

#define ATA_MASTER_CHS			0xA0
#define ATA_SLAVE_CHS			0xB0

#define ATA_LBA_MODE		0x01
#define ATA_CHS_MODE		0x00

#define ATA_SETPARAM		0x01
#define ATA_CALIBRATE	0x10
#define ATA_READ			0x20
#define ATA_WRITE			0x30
#define ATA_VERIFY		0x40
#define ATA_FORMAT		0x50
#define ATA_SEEK			0x70
#define ATA_DIAG			0x90
#define ATA_IDENTIFY		0xEC

#define ATA_BUSY			0x80
#define ATA_READY			0x40
#define ATA_FAULT			0x20
#define ATA_SEEKDONE		0x10
#define ATA_DATAREQ		0x08
#define ATA_DATACOR		0x04
#define ATA_INDEX			0x02
#define ATA_ERROR 		0x01

struct ata_drive;//foreward declare

typedef struct
{
	u8int exists;
	struct ata_drive *drive;
	u8int status;
	u8int type;
	u32int lba_base;
	u32int lba_length;
}ata_partition_t;

typedef struct
{
	u16int data;
	u16int error;
	u16int features;
	u16int sectors;
	u16int LBA_low;
	u16int LBA_mid;
	u16int LBA_high;
	u16int drive_head;
	u16int status;
	u16int command;
	u16int alt_status;
	u16int control;
}ata_ports_t;

typedef struct ata_drive
{
	u32int id;				//0xA0=master 0xB0=slave
	u32int index;
	u32int mode;				//1=lba anything else is illegal (for now)
	u32int size;				//size of the disk in bytes
	u32int blocks;
	u32int block_size;
   u32int cylinders;
   u32int heads;
   u32int sectors;
   u32int current_block;
	
	ata_ports_t ports;

	ata_partition_t partitions[4];	//4 primary partitions.

	s16int buffer[1024];//a 1 megabyte buffer (transfer area / cache)

	s8int serial_number[21];
   s8int firmware_revision[9];
   s8int model[41];

}ata_drive_t;

void init_ata(void);

//void ata_dump_drive_info(window *win, ata_drive_t *d);

ata_drive_t *ata_get_drive(u32int driveID);

int ata_read_drive(ata_drive_t *d, u8int *data, u32int sector, u32int offset, u32int length);
int ata_write_drive(ata_drive_t *d, s8int *data, u32int sector, u32int offset, u32int length);

int ata_read_partition(ata_partition_t *p, u8int *data, u32int sector, u32int offset, u32int length);

void init_ata_interface(void);
#endif
